package face.pay.api.wechat.service.impl;

import com.alibaba.fastjson.JSON;
import com.face.pay.IPayConfigServer;
import com.face.pay.WxApiConfig;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayRequest;
import com.github.wxpay.sdk.WXPayUtil;
import face.pay.api.wechat.service.IFaceCodeService;
import face.pay.dao.*;
import face.pay.entity.*;
import face.pay.api.wechat.param.FaceParam;
import face.pay.util.bean.JavaBeanUtils;
import face.pay.util.ResultMessage;
import face.pay.util.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

/**
 * @Auther: zkj
 * @Date: 2019/7/27 15:49
 * @Description:
 */
@Service
@Slf4j
public class FaceCodeServiceImpl extends AbstractOrderSafeServiceImpl implements IFaceCodeService {


    private final static  String domain = "payapp.weixin.qq.com";

    private final static  String urlSuffix = "/face/get_wxpayface_authinfo";


    @Autowired
    private TerminalInfoDao terminalInfoDao;

    @Autowired
    private StoreInfoDao storeInfoDao;

    @Autowired
    private EnterpriseInfoDao enterpriseInfoDao;

    @Autowired
    private OemInfoDao oemInfoDao;

    @Autowired
    private IPayConfigServer iWxPayConfigServer;


    @Override
    @Transactional(rollbackFor =  Exception.class)
    public ResultMessage getWxpayFaceAuthInfo(String jsonData) {
        try {

            log.info("获取刷脸凭证："+jsonData);

            FaceParam faceCodeParam = JSON.parseObject(jsonData, FaceParam.class);

            /**
             * 要进行参数验证 金额要大于0
             */

            Long nowTime = System.currentTimeMillis();

            faceCodeParam.setNow(TimeUtils.toSecs(nowTime));
            /**
             * 随机字符串
             */
            String nonce_str = WXPayUtil.generateNonceStr();

            faceCodeParam.setNonce_str(nonce_str);

            faceCodeParam.setSign_type(WXPayConstants.SignType.MD5.toString());


            String deviceId = StringUtils.isBlank(faceCodeParam.getDevice_id())?"":faceCodeParam.getDevice_id();

            String imei = StringUtils.isBlank(faceCodeParam.getImei())?"":faceCodeParam.getImei();


            /**
             * 设备查询
             */

            TerminalInfo terminalInfo = this.terminalInfoDao.getByDeviceId(deviceId);

            //&& imei.equals(terminalInfo.getImei())
            if (terminalInfo != null && terminalInfo.getStoreId()!=null && StringUtils.isNotBlank(imei) ) {

                log.info("设备信息:"+terminalInfo);
                OrderInfo orderInfo = new OrderInfo();

                Integer storeId = terminalInfo.getStoreId();
                Integer oemId   = terminalInfo.getOemId();
                Integer userId  = terminalInfo.getUserId();

                StoreInfo storeInfo = this.storeInfoDao.getById(storeId);

                if(storeInfo!=null) {

                    log.info("门店信息:" + storeInfo.toString());


                    WxApiConfig wxApiConfig = this.iWxPayConfigServer.getConfig(oemId);

                    if (wxApiConfig.validate()) {

                        WXPayRequest wxPayRequest = new WXPayRequest(wxApiConfig);

                        OemInfo oemInfo = this.oemInfoDao.getOemInfoById(oemId);


                        Integer enterpriseId = storeInfo.getEnterpriseId();

                        EnterpriseInfo enterpriseInfo = this.enterpriseInfoDao.getById(enterpriseId);
                        /**
                         * 获取OEM 微信服务商信息
                         */
                        String appId = wxApiConfig.getAppID();
                        String apiKey = wxApiConfig.getKey();
                        String mchId = wxApiConfig.getMchID();

                        String subMchId = enterpriseInfo.getWxSubMchId();

                        if (StringUtils.isBlank(subMchId)) {
                            return ResultMessage.createFail("商家商户号错误");
                        }

                        faceCodeParam.setAppid(appId);
                        faceCodeParam.setMch_id(mchId);
                        faceCodeParam.setSub_mch_id(subMchId);

                        faceCodeParam.setStore_id(String.valueOf(storeId));
                        faceCodeParam.setStore_name(storeInfo.getName());

                        Map<String, String> map = JavaBeanUtils.toMap(faceCodeParam);

                        /**
                         * 密钥
                         */
                        String xml = WXPayUtil.generateSignedXml(map, apiKey);

                        log.info("获取凭证 推送到微信服务器消息xml" + xml);


                        String result = wxPayRequest.requestOnce(domain, urlSuffix, xml , false);

                        Map<String, String> resultMap = WXPayUtil.xmlToMap(result);

                        log.info("返回结果 " + result);
                        String return_code = resultMap.get("return_code");
                        if ("SUCCESS".equals(return_code)) {

                            resultMap.put("store_id", String.valueOf(storeId));
                            resultMap.put("device_id", deviceId);

                            ResultMessage resultMessage = ResultMessage.createSuccess(resultMap);

                            String json = JSON.toJSONString(resultMessage);
                            log.info("获取凭证正确:返回设备请求:" + json);

                            return resultMessage;
                        } else {
                            String error = resultMap.get("return_msg");
                            log.info("获取凭证失败:" + error);
                            return ResultMessage.createFail(error);
                        }
                    } else {
                        log.info("配置错误");
                        return ResultMessage.createFail("服务商微信配置错误");

                    }
                }else {
                    log.info("门店信息错误");
                    return ResultMessage.createFail("门店信息错误");
                }

            }else {
                log.info("设备信息验证有误");
                return  ResultMessage.createFail("设备不存在或设备没有绑定门店");
            }

        } catch (Exception e) {
            log.error("获取凭证异常", e);
            return ResultMessage.createError();
        }

    }

}
